package com.novunda.platform.web;

import com.novunda.cas.push.client.response.ApprovePushResponse;
import com.novunda.cas.push.client.response.CommonResponse;
import com.novunda.platform.common.exception.NovException;
import com.novunda.platform.common.reponse.ApproveResponse;
import com.novunda.platform.common.reponse.QrCodeStatusResponse;
import com.novunda.platform.common.utils.StringUtil;
import com.novunda.platform.common.web.controller.BaseController;
import com.novunda.platform.enums.ValidateExceptionEnum;
import com.novunda.platform.security.LoginException;
import com.novunda.platform.services.CenterService;
import com.novunda.platform.services.PushService;
import com.novunda.tca.tdk.domain.ResourceDataInfo;
import com.novunda.tca.tdk.http.OltuURLConnectionClient;
import com.novunda.tca.tdk.utils.ConfigResource;
import com.novunda.tca.tdk.utils.GsonUtils;
import org.apache.oltu.oauth2.client.OAuthClient;
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse;
import org.apache.oltu.oauth2.client.response.OAuthResourceResponse;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.types.GrantType;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.regex.Pattern;

/**
 * ..、
 * 推送demo调用
 *
 * @author yangg
 * @since 2016/10/13.
 */
@Controller
@RequestMapping("/sys/demo")
public class PushController extends BaseController {
    @Autowired
    private PushService pushService;
    @Autowired
    private CenterService centerService;

    private static final Pattern COMPILE1 = Pattern.compile("\\|");

    @RequestMapping({"index", ""})
    public String index(Model model) {
        return "modules/sys/push";
    }

    /**
     * 普通推送
     *
     * @param receiver 接收者
     * @param title    标题
     * @param content  内容
     * @return 推送结果
     */
    @RequestMapping(value = "normal", produces = "application/json; charset=UTF-8")
    @ResponseBody
    public String normalPush(String receiver, String title, String content) {
        CommonResponse commonResponse = new CommonResponse();
        try {
            commonResponse = pushService.normalPush(receiver, title, content);
        } catch (Exception e) {
            LOG.error("推送失败", e);
        }
        return com.novunda.platform.common.utils.GsonUtils.getInstance().toJson(commonResponse);
    }

    /**
     * 广播
     *
     * @param title   标题
     * @param content 内容
     * @return 推送结果
     */
    @RequestMapping(value = "broad", produces = "application/json; charset=UTF-8")
    @ResponseBody
    public String broadCast(String title, String content) {
        CommonResponse commonResponse = new CommonResponse();
        try {
            commonResponse = pushService.broadCast(title, content);
        } catch (Exception e) {
            LOG.error("推送失败", e);
        }
        return com.novunda.platform.common.utils.GsonUtils.getInstance().toJson(commonResponse);
    }

    /**
     * 审批推送
     *
     * @param receiver 接收者
     * @param title    标题
     * @param content  内容
     * @return 推送结果
     */
    @RequestMapping("approve")
    @ResponseBody
    public String approvePush(String receiver, String title, String content) {
        ApprovePushResponse approvePushResponse = new ApprovePushResponse();

        try {
          approvePushResponse =  pushService.approvePush(receiver, title, content);
        } catch (Exception e) {
            LOG.error("推送失败", e);
        }
        return  GsonUtils.getInstance().toJson(approvePushResponse);
    }

    /**
     * 获取审批状态
     *
     * @param code 二维码状态获取参数
     * @return 审批状态
     */
    @RequestMapping("status")
    @ResponseBody
    public String status(String code) {
        QrCodeStatusResponse statusResponse;
        try {
            statusResponse = centerService.qrStatus(code);
        } catch (NovException e) {
            statusResponse = new QrCodeStatusResponse();
            statusResponse.setReturnCode(-1);
            statusResponse.setReturnMessage(e.getMessage());
        } catch (Exception e) {
            LOG.error("获取二维码状态失败", e);
            statusResponse = new QrCodeStatusResponse();
            statusResponse.setReturnCode(-1);
            statusResponse.setReturnMessage("inner error");
        }

        return com.novunda.platform.common.utils.GsonUtils.getInstance().toJson(statusResponse);
    }

    /**
     * 审批回调
     *
     * @param request  请求
     * @param response 响应
     * @param model    提示块
     * @return 绑定结果
     */
    @RequestMapping("pushBack")
    @ResponseBody
    public ApproveResponse bindBack(HttpServletRequest request, HttpServletResponse response, Model model) {

        ApproveResponse approveResponse = new ApproveResponse();
        try {

            ResourceDataInfo resourceDataInfo = getResources(request);

            if (resourceDataInfo == null || resourceDataInfo.getReturnCode() != 0) {
                throw new NovException(ValidateExceptionEnum.INVALID_RESORCE_NULL);
            }

            String validationData = resourceDataInfo.getValidationData();

            String qrData = resourceDataInfo.getQrdata();

            if (StringUtil.isEmpty(validationData) || COMPILE1.split(validationData).length <= 0 || StringUtil.isEmpty(COMPILE1.split(validationData)[1])) {
                throw new NovException(ValidateExceptionEnum.INVALID_RESORCE_NULL);
            }

            String approveResult = COMPILE1.split(validationData)[1];
            approveResponse.setResult(approveResult);
            approveResponse.setReturnCode(0);
            approveResponse.setReturnMessage("ok");
        } catch (NovException e) {
            approveResponse.setReturnCode(-1);
            approveResponse.setReturnMessage(e.getMessage());
        } catch (Exception e) {
            LOG.warn(e.getMessage(), e);
            approveResponse.setReturnCode(-1);
            approveResponse.setReturnMessage("error");
        }

        return approveResponse;

    }


    protected String getCode(ServletRequest request) {
        String code = "code";
        return WebUtils.getCleanParam(request, code);
    }

    /**
     * 从请求内获取TCA响应返回数据信息
     *
     * @param request 请求
     * @return TCA返回数据信息
     */
    private ResourceDataInfo getResources(HttpServletRequest request) {

        ResourceDataInfo resourceDataInfo;
        try {

            OAuthClient oAuthClient = new OAuthClient(new OltuURLConnectionClient());

            OAuthClientRequest accessTokenRequest = OAuthClientRequest.tokenLocation(ConfigResource.accessURI)
                    .setGrantType(GrantType.AUTHORIZATION_CODE).setClientId(ConfigResource.clientId)
                    .setClientSecret(ConfigResource.clientSecret).setCode(request.getParameter("code"))
                    .setRedirectURI(ConfigResource.webRedirectUrl).buildQueryMessage();
            OAuthJSONAccessTokenResponse oAuthResponse = oAuthClient.accessToken(accessTokenRequest, "POST");
            String accessToken = oAuthResponse.getAccessToken();
            OAuthClientRequest userInfoRequest = OAuthClientRequest.tokenLocation(ConfigResource.resourceURI)
                    .setParameter("client_id", ConfigResource.clientId).setParameter("access_token", accessToken).buildQueryMessage();
            OAuthResourceResponse resourceResponse = oAuthClient.resource(userInfoRequest, "GET", OAuthResourceResponse.class);
            String content = resourceResponse.getBody();
            resourceDataInfo = GsonUtils.getInstance().fromJson(content, ResourceDataInfo.class);

        } catch (OAuthSystemException | OAuthProblemException e) {
            throw new LoginException("资源获取失败", e);
        }

        return resourceDataInfo;
    }
}
